import { onMounted, reactive, ref } from 'vue'

type ResponseTypes = {
  status: number
  info: string
  infocode: string
  [key: string]: any
}
// 请求方法类型
type RequestService<R = any, P extends any[] = any> = (...args: P) => Promise<R>
// 参数配置
type RequestOptions<T = ResponseTypes, P = any> = {
  manual?: boolean
  defautDataValue?: T
  onSuccess?: (data: T, params?: P) => void
  onError?: (e: any) => void
}

function useRequest<T = any, P extends any[] = any>(
  request: RequestService<T>,
  options: RequestOptions<T, P> = {}
) {
  const data = ref<T | null>(null)

  const loading = ref(false)

  const error = ref(false)

  // 请求执行函数
  const run = (...args: P) => {
    loading.value = true
    error.value = false
    request(...args)
      .then((responseData: any) => {
        data.value = responseData
        options.onSuccess && options.onSuccess(responseData, args)
      })
      .catch((e) => {
        error.value = true
        options.onError && options.onError(e)
      })
      .finally(() => {
        loading.value = false
      })
  }

  onMounted(() => {
    if (!options.manual) {
      run(...([] as any))
    }
  })

  return {
    data,
    loading,
    error,
    run,
  }
}

export default useRequest
